import CryptoJS from 'crypto-js';

import {
    encryptoPBKDF2
} from './Component/Crypto.js';

import {
    setToken
} from './Component/token.js';

import {
    server
} from '../server.js';

import {
    storeFile
} from './Component/StoreFile.js';

import {
    mysqlConnectPromise,
    mysqlQueryPromise
} from './Component/MySQLPromise.js';

import {
    respondJson,
    respondSendMessage,
    respondReqDataMalformation,
    respondServerSQLError,
    respondServerQueryError
} from './Component/Respond.js';

export const HLT = async (req, res, next) => {

    let name = req.query.name;
    let category = req.query.category;
    let id = req.query.id;

    let pool = req.app.locals.pool;

    let connection = await mysqlConnectPromise(pool);

    if (!connection) {
        respondServerSQLError(res);
        return;
    }

    function searchCategory(str) {
        if (str.search('主食') != -1)
            return '主食';
        if (str.search('蔬果') != -1)
            return '蔬果';
        if (str.search('奶类') != -1)
            return '奶类';
        if (str.search('肉类') != -1)
            return '肉蛋类';
        if (str.search('坚果') != -1)
            return '坚果豆类';
        if (str.search('调味品') != -1)
            return '调味品';
        if (str.search('饮料') != -1)
            return '饮料';
        if (str.search('零食') != -1)
            return '零食';
        return '其他';

    }

    if (name) {

        let results = await mysqlQueryPromise(connection, `SELECT * from HLT where 名称 like '%${name}%'`);

        if (!results) {
            respondServerQueryError(connection, res);
            return;
        }

        // let today = new Date().toLocaleDateString().replaceAll('/', '-');

        for (let i = 0; i < results.length; i++) {
            const element = results[i];
            let c
            if (element.分类) {
                c = searchCategory(element.分类);
                let results0 = await mysqlQueryPromise(connection, `update dailySearch set ${c}=${c}+1 where today = curdate()`);
            }
        }

        respondSendMessage(connection, res, 200, results);

    } else if (category) {

        let results = await mysqlQueryPromise(connection, `SELECT * from HLT where 分类 like '%${category}%'`);

        if (!results) {
            respondServerQueryError(connection, res);
            return;
        }

        if (results.length != 0) {
            // let today = new Date().toLocaleDateString().replaceAll('/', '-');

            const element = results[0];
            let c = searchCategory(element.分类);

            let results0 = await mysqlQueryPromise(connection, `update dailySearch set ${c}=${c}+1 where today = curdate()`);
        }

        respondSendMessage(connection, res, 200, results);

    } else if (id) {

        let results = await mysqlQueryPromise(connection, `SELECT * from HLT where id like '${id}'`);

        if (!results) {
            respondServerQueryError(connection, res);
            return;
        }

        // let today = new Date().toLocaleDateString().replaceAll('/', '-');

        for (let i = 0; i < results.length; i++) {
            const element = results[i];
            let c = searchCategory(element.分类);
            let results0 = await mysqlQueryPromise(connection, `update dailySearch set ${c}=${c}+1 where today = curdate()`);
        }

        respondSendMessage(connection, res, 200, results);

    } else {

        respondJson(connection, res, 200, {
            status: false,
            errinfo: 'none results!'
        })

    }

}

export const hltAll = async (req, res, next) => {

    let pool = req.app.locals.pool;

    let connection = await mysqlConnectPromise(pool);

    if (!connection) {
        respondServerSQLError(res);
        return;
    }

    let results = await mysqlQueryPromise(connection, `SELECT * from HLT`);

    if (!results) {
        respondServerQueryError(connection, res);
        return;
    }

    respondSendMessage(connection, res, 200, results);

}

export const feedback = async (req, res, next) => {

    let body = req.body;
    let data = req.data;

    if (!(body.content || body.imageuri)) {
        respondReqDataMalformation(res);
        return;
    }

    let pool = req.app.locals.pool;

    let connection = await mysqlConnectPromise(pool);

    if (!connection) {
        respondServerSQLError(res);
        return;
    }

    let results = await mysqlQueryPromise(connection, `select userid, password from users where username like '${data.name}'`);

    if (!results) {
        respondServerQueryError(connection, res);
        return;
    } else if (results == 0) {
        respondJson(connection, res, 200, {
            status: false,
            errinfo: '该用户未注册！'
        })
        return;
    }

    if (data.pw != encryptoPBKDF2(results[0].password)) {
        respondJson(connection, res, 200, {
            status: false,
            errinfo: '无效token！'
        })
        return;
    }

    let info = {
        userid: results[0].userid,
        username: data.name,
        content: body.content,
        imageuri: body.imageuri ? body.imageuri.split('2333')[1] : undefined
    }

    let results0 = await mysqlQueryPromise(connection, `select count(*) as fb_count from feedback`);

    if (!results0) {
        respondServerQueryError(connection, res);
        return;
    }

    let fb_count = 10000000 + results0[0].fb_count + 1;

    let results1 = await mysqlQueryPromise(connection, `insert into feedback(fbid, userid, username, content, image) values (${fb_count},${info.userid},"${info.username}","${info.content}","${info.imageuri}")`);

    if (!results1) {
        respondServerQueryError(connection, res);
        return;
    }

    respondJson(connection, res, 200, {
        status: true,
        info: '反馈成功！'
    })

}

export const getFeedback = async (req, res, next) => {

    let pool = req.app.locals.pool;

    let connection = await mysqlConnectPromise(pool);

    if (!connection) {
        respondServerSQLError(res);
        return;
    }

    let results = await mysqlQueryPromise(connection, `SELECT * from feedback`);

    if (!results) {
        respondServerQueryError(connection, res);
        return;
    }

    for (let i = 0; i < results.length; i++) {
        results[i].image = server + results[i].image;
    }

    respondSendMessage(connection, res, 200, results);

}

export const updateUserInfo = async (req, res, next) => {

    let body = req.body;
    let data = req.data;

    if (!(body.gender && body.birthday && body.height && body.weight && body.idealWeight)) {
        respondReqDataMalformation(res);
        return;
    }

    let pool = req.app.locals.pool;

    let connection = await mysqlConnectPromise(pool);

    if (!connection) {
        respondServerSQLError(res);
        return;
    }

    let results = await mysqlQueryPromise(connection, `select userid, password from users where username like '${data.name}'`);

    if (!results) {
        respondServerQueryError(connection, res);
        return;
    } else if (results == 0) {
        respondJson(connection, res, 200, {
            status: false,
            errinfo: '该用户未注册！'
        })
        return;
    }

    if (data.pw != encryptoPBKDF2(results[0].password)) {
        respondJson(connection, res, 200, {
            status: false,
            errinfo: '无效token！'
        })
        return;
    }

    let info = {
        userid: results[0].userid,
        username: data.name,
        gender: body.gender == '男' ? true : false,
        birthday: body.birthday, // YYYY-MM-DD
        height: body.height,
        weight: body.weight,
        idealWeight: body.idealWeight
    }

    let results0 = await mysqlQueryPromise(connection, `select * from userinfo where userid = ${info.userid}`);

    if (!results0) {
        respondServerQueryError(connection, res);
        return;
    }
    if (results0[0]) {
        await mysqlQueryPromise(connection, `delete from userinfo where userid = ${info.userid}`);
        await mysqlQueryPromise(connection, `insert into userinfo(userid, username, gender, birthday, height, weight, idealWeight) values (${info.userid},'${info.username}',${info.gender},'${info.birthday}', ${info.height},${info.weight},${info.idealWeight})`);
        respondJson(connection, res, 200, {
            status: true,
            info: '更新成功！'
        })
    } else {
        await mysqlQueryPromise(connection, `insert into userinfo(userid, username, gender, birthday, height, weight, idealWeight) values (${info.userid},'${info.username}',${info.gender},'${info.birthday}', ${info.height},${info.weight},${info.idealWeight})`);
        respondJson(connection, res, 200, {
            status: true,
            info: '更新成功！'
        })
    }
}

export const getUserInfo = async (req, res, next) => {

    let data = req.data;

    let pool = req.app.locals.pool;

    let connection = await mysqlConnectPromise(pool);

    if (!connection) {
        respondServerSQLError(res);
        return;
    }

    let results = await mysqlQueryPromise(connection, `select * from userinfo where username like '${data.name}'`);

    if (!results) {
        respondServerQueryError(connection, res);
        return;
    }

    respondSendMessage(connection, res, 200, results);

}

export const collectFood = async (req, res, next) => {

    const id = req.body.id
    const data = req.data

    if (!id) {
        respondReqDataMalformation(res);
        return;
    }

    let pool = req.app.locals.pool;

    let connection = await mysqlConnectPromise(pool);

    if (!connection) {
        respondServerSQLError(res);
        return;
    }

    let results = await mysqlQueryPromise(connection, `select * from usercollect where username like '${data.name}'`);

    if (!results) {
        respondServerQueryError(connection, res);
        return;
    }

    let hasInserded = false;

    for (let i = 0; i < results.length; i++) {
        const element = results[i];
        if (element.foodid == id) {
            hasInserded = true;
            break;
        }
    }

    if (hasInserded) {
        let results0 = await mysqlQueryPromise(connection, `delete from usercollect where username like '${data.name}' and foodid like '${id}'`);

        if (!results0) {
            respondServerQueryError(connection, res);
            return;
        }

        respondJson(connection, res, 200, {
            status: true,
            errinfo: '取消收藏成功！'
        })
        return;
    }

    let results1 = await mysqlQueryPromise(connection, `insert into usercollect(username, foodid) values('${data.name}','${id}')`);

    if (!results1) {
        respondServerQueryError(connection, res);
        return;
    }

    respondJson(connection, res, 200, {
        status: true,
        info: '收藏成功！'
    })

}

export const getUserCollect = async (req, res, next) => {

    let data = req.data;

    let pool = req.app.locals.pool;

    let connection = await mysqlConnectPromise(pool);

    if (!connection) {
        respondServerSQLError(res);
        return;
    }

    let results = await mysqlQueryPromise(connection, `select * from usercollect where username like '${data.name}'`);

    if (!results) {
        respondServerQueryError(connection, res);
        return;
    }

    let resArr = [];
    let queryStr = '';

    for (let i = 0; i < results.length; i++) {
        let obj = {
            username: results[i].username,
            foodid: results[i].foodid
        }
        resArr[i] = obj;
        queryStr += `select 图片地址, 热量, 名称 from hlt where id like '${results[i].foodid}'`;
        if (i != results.length - 1) {
            queryStr += ' union ';
        }
    }

    if (!queryStr) {
        respondSendMessage(connection, res, 200, null);
        return;
    }

    let results0 = await mysqlQueryPromise(connection, queryStr);

    if (!results0) {
        respondServerQueryError(connection, res);
        return;
    }

    for (let i = 0; i < results0.length; i++) {
        resArr[i].image = results0[i].图片地址;
        resArr[i].heat = results0[i].热量;
        resArr[i].name = results0[i].名称;
    }

    respondSendMessage(connection, res, 200, resArr);

}

export const isCollect = async (req, res, next) => {

    let data = req.data;
    let param = req.query.foodid;

    if (!param && param == 'undifined') {
        respondReqDataMalformation(res);
        return;
    }

    let pool = req.app.locals.pool;

    let connection = await mysqlConnectPromise(pool);

    if (!connection) {
        respondServerSQLError(res);
        return;
    }

    let results = await mysqlQueryPromise(connection, `select * from usercollect where username like '${data.name}' and foodid like '${param}'`);

    if (!results) {
        respondServerQueryError(connection, res);
        return;
    }

    if (results[0]) {
        respondJson(connection, res, 200, {
            status: true
        })
        return;
    }
    respondJson(connection, res, 200, {
        status: false
    })

}

export const usersSignup = async (req, res, next) => {

    //AES解密
    const body = req.body;
    console.log(body);

    var uri = body.uri;
    var base64 = body.base64;
    var email = body.email;
    var username = body.username;
    var password = body.password;

    if (!(uri && base64 && email && username && password)) {
        respondReqDataMalformation(res);
        return;
    }

    storeFile(base64, uri, './public/avatarImage/', async (filebase) => {

        if (filebase == '存储失败!') {
            res.status(200);
            res.json({
                status: false,
                errinfo: '头像存储失败！'
            });
            return;
        }

        var key = CryptoJS.enc.Utf8.parse('hu8j9r3gk4ord42n');
        var initialVector = CryptoJS.enc.Utf8.parse('kkmhed7036nbtfc8');

        var decrypted = CryptoJS.AES.decrypt(password, key, {
            iv: initialVector,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7
        });

        decrypted = CryptoJS.enc.Utf8.stringify(decrypted);

        let pool = req.app.locals.pool;

        let connection = await mysqlConnectPromise(pool);

        if (!connection) {
            respondServerSQLError(res);
            return;
        }

        let results = await mysqlQueryPromise(connection, `SELECT max(userid) as id_count from users`);

        if (!results) {
            respondServerQueryError(connection, res);
            return;
        }

        let id_count;
        let avataruri = '/avatarImage/' + filebase;

        id_count = 10000000 + results[0].id_count + 1;

        let results0 = await mysqlQueryPromise(connection, `INSERT INTO users(userid, username, password, avataruri, email, isSignOff) values(${id_count}, '${username}', '${decrypted}', '${avataruri}', '${email}', ${false})`);

        if (!results0) {
            respondServerQueryError(connection, res);
            return;
        }

        respondJson(connection, res, 200, {
            status: true,
            info: '注册成功!'
        })

    })

}

export const usersSignin = async (req, res, next) => {

    const body = req.body

    var username = body.username;
    var password = body.password;

    if (!(username && password)) {
        respondReqDataMalformation(res);
        return;
    }

    let pool = req.app.locals.pool;

    let connection = await mysqlConnectPromise(pool);

    if (!connection) {
        respondServerSQLError(res);
        return;
    }

    let results = await mysqlQueryPromise(connection, `SELECT * from users where username like '${username}'`);

    if (!results) {
        respondServerQueryError(connection, res);
        return;
    } else if (results.length == 0) {
        respondJson(connection, res, 200, {
            status: false,
            errinfo: '该用户未注册!'
        })
        return;
    }

    let derivedKey = CryptoJS.PBKDF2(results[0].password, 'iry962g6wd2w39fw', {
        iterations: 100,
        keySize: 32,
        hasher: CryptoJS.algo.SHA512
    });

    let pw = derivedKey.toString();
    if (pw !== password) {
        console.log(pw)
        respondJson(connection, res, 200, {
            status: false,
            errinfo: '密码错误!'
        })
        return;
    }

    setToken(username, password).then((data) => {
        respondJson(connection, res, 200, {
            status: true,
            avataruri: server + results[0].avataruri,
            token: data
        })
        return;
    })

}

export const getMealRecord = async (req, res, next) => {

    const data = req.data;
    const date = req.body.date;

    let pool = req.app.locals.pool;

    let connection = await mysqlConnectPromise(pool);

    if (!connection) {
        respondServerSQLError(res);
        return;
    }

    let trueRes = await mysqlQueryPromise(connection, `select * from dailymeal where username like '${data.name}' and date like '${date}'`);

    if (!trueRes) {
        respondServerQueryError(connection, res);
        return;
    }

    for (let i = 0; i < trueRes.length; i++) {

        let results = await mysqlQueryPromise(connection, `select * from hlt where id like '${trueRes[i].foodid}'`);

        trueRes[i].food = results[0];

    }

    respondSendMessage(connection, res, 200, trueRes);

    return;

}

export const addMealRecord = async (req, res, next) => {

    const data = req.data;
    const body = req.body;

    let date = body.date;
    let foodid = body.foodid;
    let whichMeal = body.whichMeal;
    let value = body.value;
    let username = data.name;

    if (!(username && date && foodid && whichMeal && value)) {
        respondReqDataMalformation(res);
        return;
    }

    let pool = req.app.locals.pool;

    let connection = await mysqlConnectPromise(pool);

    if (!connection) {
        respondServerSQLError(res);
        return;
    }

    let results = await mysqlQueryPromise(connection, `select max(mealRecord) as record_count from dailymeal`);

    if (!results) {
        respondServerQueryError(connection, res);
        return;
    }

    let record_count = 10000000 + results[0].record_count + 1;

    let results0 = await mysqlQueryPromise(connection, `insert into dailymeal(mealRecord,username,foodid,whichMeal,date,value) values(${record_count},'${username}','${foodid}','${whichMeal}','${date}','${value}')`);

    if (!results0) {
        respondServerQueryError(connection, res);
        return;
    }

    respondJson(connection, res, 200, {
        status: true,
        mealRecord: record_count
    })

}

export const deleteMealRecord = async (req, res, next) => {

    const data = req.data;
    const mealRecord = req.body.mealRecord;

    if (!mealRecord) {
        respondReqDataMalformation(res);
        return;
    }

    let pool = req.app.locals.pool;

    let connection = await mysqlConnectPromise(pool);

    if (!connection) {
        respondServerSQLError(res);
        return;
    }

    let results = await mysqlQueryPromise(connection, `delete from dailymeal where mealRecord = ${mealRecord}`);

    if (!results) {
        respondServerQueryError(connection, res);
        return;
    }

    respondJson(connection, res, 200, {
        status: true,
        info: 'success'
    })

}

export const getUserSignature = async (req, res, next) => {

    let data = req.data;

    let pool = req.app.locals.pool;

    let connection = await mysqlConnectPromise(pool);

    if (!connection) {
        respondServerSQLError(res);
        return;
    }

    let results = await mysqlQueryPromise(connection, `select * from usersignature where username like '${data.name}'`);

    if (!results) {
        respondServerQueryError(connection, res);
        return;
    }

    respondSendMessage(connection, res, 200, results);

}

export const updateUserSignature = async (req, res, next) => {

    let data = req.data;

    let body = req.body;

    if (!body.words) {
        respondReqDataMalformation(res);
        return;
    }

    let pool = req.app.locals.pool;

    let connection = await mysqlConnectPromise(pool);

    if (!connection) {
        respondServerSQLError(res);
        return;
    }

    let results0 = await mysqlQueryPromise(connection, `select * from usersignature where username like '${data.name}'`);
    
    if (!results0) {
        respondServerQueryError(connection, res);
        return;
    }

    if (results0[0]) {
        await mysqlQueryPromise(connection, `update usersignature set words = '${body.words}' where username like '${data.name}'`);
        respondJson(connection, res, 200, {
            status: true,
            info: 'update success!'
        })
    } else {
        await mysqlQueryPromise(connection, `insert into usersignature(username, words) values ('${data.name}', '${body.words}')`);
        respondJson(connection, res, 200, {
            status: true,
            info: 'update success!'
        })
    }

}